package commands;

import java.util.StringTokenizer;

import exceptions.ParseException;
import expression.Expression;
import expression.Sum;
import memory.Memory;

public class ConditionalCommand extends Command {

	public ConditionalCommand(String command, Memory memory, int lineNumber) throws ParseException {
		super(lineNumber);
		this.memory = memory;
		
		
		if (new StringTokenizer(command).nextToken().equals("if")) {
			command = fixString(command);
			type = Type.IF;
			command = command.substring(command.indexOf("if") + 2, command.length() - 1);
		} else {
			command = fixString(command);
			type = Type.WHILE;
			command = command.substring(command.indexOf("while") + 5, command.length() - 1);
		}
		operator = new LogicalOperator(command, memory);
	}

	public enum Type {
		WHILE, IF;
	}

	Memory memory;
	Type type;
	Command trueNext, falseNext;
	LogicalOperator operator;

	@Override
	public void run() {
		return;
	}

	@Override
	public Command getNext() {
		if (operator.check())
			return trueNext;
		else
			return falseNext;
	}

	public void setNext(Command command) {
		this.trueNext = command;
	}

	public void setFalseNext(Command falseNext) {
		this.falseNext = falseNext;
	}
	
	
	
	public Type getType() {
		return type;
	}

	public Command getTrueNext() {
		return trueNext;
	}
}

class LogicalOperator {
	enum Type {
		EQ, LE, LT, GT, GE, NE;

		static String[] marks = new String[] { "==", "<=", ">=", "<", ">", "!=" };
		static Type[] types = new Type[] { EQ, LE, GE, LT, GT, NE };
	}

	Type type;
	Expression left, right;

	boolean check() {
		int leftValue = left.calculate();
		int rightValue = right.calculate();
		switch (type) {
		case EQ:
			return leftValue == rightValue;
		case LE:
			return leftValue <= rightValue;
		case LT:
			return leftValue < rightValue;
		case GT:
			return leftValue > rightValue;
		case GE:
			return leftValue >= rightValue;
		case NE:
			return leftValue != rightValue;
		default:
			return false;
		}
	}

	public LogicalOperator(String exp, Memory memory) throws ParseException {
		for (int i = 0; i < Type.types.length; i++) {
			int posOfOperator = exp.indexOf(Type.marks[i]);
			if (posOfOperator <= 0) {
				continue;
			}
			if (posOfOperator >= exp.length() - 1) {
				continue;
			}
			type = Type.types[i];
			left = new Sum(exp.substring(0, posOfOperator), memory);
			right = new Sum(exp.substring(posOfOperator
					+ Type.marks[i].length()), memory);
			return;
		}
		throw new ParseException(exp + " is not valid logical expression");
	}
}